/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.jm.financeiro.view;

import br.jm.financeiro.datamodel.LazyContaPagar;
import br.jm.financeiro.entity.ContaPagar;
import br.jm.financeiro.entity.ContaPagarParcela;
import br.jm.financeiro.filter.Funcoes;
import br.jm.financeiro.sistema.eao.ContaPagarEao;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.primefaces.context.RequestContext;
import org.primefaces.model.LazyDataModel;

/**
 *
 * @author joao
 */
public class ContaPagarBean implements Serializable {

    private static final long serialVersionUID = 1L;
    private ContaPagar selectedContaPagar = new ContaPagar();
    private ContaPagarParcela selectContaPagarParcela;
    private final ContaPagarEao ContaPagarJpa;
    private LazyDataModel<ContaPagar> lazyModel;
    private List<ContaPagarParcela> lazyContaPagarParcela;
    private FacesMessage msg;
    private int numParcela = 1;
    private boolean parcela = true;
    private Date dataAtual = new Date();
    private Date dataVenc = new Date();
    private boolean salvar;
    private int rowid;

    public ContaPagarBean() {
        ContaPagarJpa = ContaPagarEao.getInstance();

        selectedContaPagar = new ContaPagar();
        selectContaPagarParcela = new ContaPagarParcela();
        lazyContaPagarParcela = new ArrayList<>();

        lazyModel = new LazyContaPagar(ContaPagarJpa);
    }

    public LazyDataModel<ContaPagar> getLazyModel() {
        return lazyModel;
    }

    public void setLazyModel(LazyDataModel<ContaPagar> lazyModel) {
        this.lazyModel = lazyModel;
    }

    public ContaPagar getSelectedContaPagar() {
        return selectedContaPagar;
    }

    public void setSelectedContaPagar(ContaPagar selectedContaPagar) {
        this.selectedContaPagar = selectedContaPagar;
    }

    public ContaPagarParcela getSelectContaPagarParcela() {
        if (selectContaPagarParcela == null) {
            selectContaPagarParcela = new ContaPagarParcela();
        }
        return selectContaPagarParcela;
    }

    public void setSelectContaPagarParcela(ContaPagarParcela selectContaPagarParcela) {
        this.selectContaPagarParcela = selectContaPagarParcela;
    }

    public List<ContaPagarParcela> getLazyContaPagarParcela() {
        return lazyContaPagarParcela;
    }

    public void setLazyContaPagarParcela(List<ContaPagarParcela> lazyContaPagarParcela) {
        this.lazyContaPagarParcela = lazyContaPagarParcela;
    }

    public void inserirPagar(ActionEvent event) {
        RequestContext context = RequestContext.getCurrentInstance();
        boolean loggedIn = false;

        try {
            if (ValidaPagar()) {
                this.selectedContaPagar.setIdPagar(null);

                ContaPagarJpa.create(this.selectedContaPagar);
                //eliminaParcelas();

                msg = new FacesMessage(FacesMessage.SEVERITY_INFO, LoginBean.AtualizaLog("", "Contas a Pagar Inserido com Sucesso: ".concat(selectedContaPagar.getDscPagar())), selectedContaPagar.getDscPagar());
                loggedIn = true;
            }
        } catch (Exception e) {
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao Inserir: " + selectedContaPagar.getDscPagar(), "");
        } finally {
            FacesContext.getCurrentInstance().addMessage(null, msg);
            context.addCallbackParam("loggedIn", loggedIn);
        }
    }

    public void alterarPagar(ActionEvent event) {
        RequestContext context = RequestContext.getCurrentInstance();
        boolean loggedIn = false;

        try {
            if (ValidaPagar()) {
                ContaPagarJpa.edit(selectedContaPagar);
                //eliminaParcelas();
                msg = new FacesMessage(FacesMessage.SEVERITY_INFO, LoginBean.AtualizaLog("", "Contas a Pagar Alterado com Sucesso: ".concat(selectedContaPagar.getDscPagar())), selectedContaPagar.getDscPagar());
                loggedIn = true;
            }
        } catch (Exception e) {
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao Alterar: " + selectedContaPagar.getDscPagar(), "");
        } finally {
            FacesContext.getCurrentInstance().addMessage(null, msg);
            context.addCallbackParam("loggedIn", loggedIn);
        }
    }

    public void excluirPagar(ActionEvent event) {
        try {

            ContaPagarJpa.destroy(selectedContaPagar);
            //eliminaParcelas();

            msg = new FacesMessage(FacesMessage.SEVERITY_INFO, LoginBean.AtualizaLog("", "Contas a Pagar Excluido com Sucesso: ".concat(selectedContaPagar.getDscPagar())), selectedContaPagar.getDscPagar());

        } catch (Exception e) {
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao Excluido: " + selectedContaPagar.getDscPagar(), "");
        } finally {
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }

    public int getNumParcela() {
        return numParcela;
    }

    public void setNumParcela(int numParcela) {
        this.numParcela = numParcela;
    }

    public boolean isParcela() {
        return parcela;
    }

    public void setParcela(boolean parcela) {
        this.parcela = parcela;
    }

    public Date getDataAtual() {
        return dataAtual;
    }

    public void setDataAtual(Date dataAtual) {
        this.dataAtual = dataAtual;
    }

    public Date getDataVenc() {
        return dataVenc;
    }

    public void setDataVenc(Date dataVenc) {
        this.dataVenc = dataVenc;
    }

    public void recalculaParcela() {
        Calendar c = Calendar.getInstance();
        int nDias = 30;
        BigDecimal parcelas;
        BigDecimal nZero = new BigDecimal(0);
        BigDecimal nVlrDocumento = new BigDecimal(0);

        try {
            if (selectedContaPagar.getVlrPagar().floatValue() <= 0) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Obrigatório digitar Valor do Documento!", selectedContaPagar.getDscPagar()));
            } else {
                lazyContaPagarParcela = new ArrayList<ContaPagarParcela>();

                // Tira o Desconto
                nVlrDocumento = selectedContaPagar.getVlrPagar().subtract(selectedContaPagar.getVlrDesconto());
                parcelas = new BigDecimal(numParcela);
                // Divide e o coloca o resto na primeira parcela
                BigDecimal[] result = nVlrDocumento.divideAndRemainder(parcelas);

                for (int i = 0; i < numParcela; i++) {
                    selectContaPagarParcela = new ContaPagarParcela();

                    selectContaPagarParcela.setIdParcela(null);
                    selectContaPagarParcela.setNumParcela((i + 1));
                    selectContaPagarParcela.setDscParcela("Parcela " + (i + 1));
                    selectContaPagarParcela.setDatVcto(dataVenc);
                    selectContaPagarParcela.setTipStatus("A");
                    selectContaPagarParcela.setVlrDescontoParcela(nZero);
                    selectContaPagarParcela.setVlrJuros(nZero);
                    selectContaPagarParcela.setVlrMultaParcela(nZero);
                    selectContaPagarParcela.setVlrPago(nZero);
                    selectContaPagarParcela.setIdPagar(selectedContaPagar);
                    selectContaPagarParcela.setVlrImposto(nZero);

                    if (i == 0) {
                        selectContaPagarParcela.setVlrParcela(result[0].add(result[1]));
                    } else {
                        selectContaPagarParcela.setVlrParcela(result[0]);
                    }

                    c.add(Calendar.DATE, nDias);
                    dataVenc = c.getTime();

                    lazyContaPagarParcela.add(selectContaPagarParcela);
                }
                selectContaPagarParcela = new ContaPagarParcela();
                this.selectedContaPagar.setContaPagarParcelaList(lazyContaPagarParcela);
            }
        } catch (Exception ex) {
            FacesContext context = FacesContext.getCurrentInstance();
            String texto = "Erro no Processamento ...";
            msg = new FacesMessage(texto);
            msg.setSeverity(FacesMessage.SEVERITY_WARN);
            context.addMessage(null, msg);
        }
    }

    public void novoDocumento(ActionEvent event) {
        try {
            selectedContaPagar = new ContaPagar();
            selectContaPagarParcela = new ContaPagarParcela();
            lazyContaPagarParcela = new ArrayList<ContaPagarParcela>();
            lazyContaPagarParcela.add(selectContaPagarParcela);

            selectedContaPagar.setContaPagarParcelaList(lazyContaPagarParcela);
            selectedContaPagar.setDatEmissao(dataAtual);
            selectedContaPagar.setPerJuros(BigDecimal.ZERO);
            selectedContaPagar.setTipJuros("D");
            selectedContaPagar.setVlrDesconto(BigDecimal.ZERO);
            selectedContaPagar.setVlrMulta(BigDecimal.ZERO);
            selectedContaPagar.setVlrPagar(BigDecimal.ZERO);

            this.salvar = true;
        } catch (Exception ex) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Erro de Procesamento ...", selectedContaPagar.getDscPagar()));
        }
    }

    public void baixarParcela(ActionEvent event) {
        BigDecimal nPercJuros = selectedContaPagar.getPerJuros().divide(new BigDecimal("100"));
        BigDecimal nPercMulta = selectedContaPagar.getVlrMulta().divide(new BigDecimal("100"));

        BigDecimal nVlrParcela = selectContaPagarParcela.getVlrParcela();
        BigDecimal nVlrDesconto = selectContaPagarParcela.getVlrDescontoParcela();
        BigDecimal nVlrTotal = selectContaPagarParcela.getVlrPago();

        BigDecimal nVlrJuros = new BigDecimal(0);
        BigDecimal nVlrMulta = new BigDecimal(0);
        BigDecimal nVlrImposto = new BigDecimal(0);

        String cTipCalculo = selectedContaPagar.getTipJuros();
        int nDias = 0;

        try {
            if (selectContaPagarParcela.getDatVcto() == null) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Data Vencimento Inválida!", selectedContaPagar.getDscPagar()));
            } else if (selectContaPagarParcela.getDatPagto() == null) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Data Pagamento Inválida!", selectedContaPagar.getDscPagar()));
            } else if (nVlrParcela.compareTo(BigDecimal.ZERO) == 0) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Valor da Parcela Obrigatório!", selectedContaPagar.getDscPagar()));
            } else if (selectContaPagarParcela.getIdBaixa() == null) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Obrigatório selecionar Tipo de Baixa!", selectedContaPagar.getDscPagar()));
            } else if (selectContaPagarParcela.getIdPagamento() == null) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Obrigatório selecionar Tipo de Pagamento!", selectedContaPagar.getDscPagar()));
            } else {
                // CALCULA NUMERO DE DIAS DE ATRASO
                if (cTipCalculo.equals("D")) {
                    nDias = (int) Funcoes.diferencaEmDias(selectContaPagarParcela.getDatVcto(), selectContaPagarParcela.getDatPagto());
                } else {
                    nDias = Funcoes.diferencaEmMeses(selectContaPagarParcela.getDatVcto(), selectContaPagarParcela.getDatPagto());
                }
                //CALCULA JUROS E MULTA
                if (nDias > 0) {
                    nVlrMulta = nVlrParcela.multiply(nPercMulta);
                    nVlrParcela = nVlrParcela.add(nVlrMulta);
                    nVlrJuros = nVlrParcela.multiply(nPercJuros).multiply(new BigDecimal(nDias));
                    nVlrTotal = nVlrJuros.add(nVlrParcela).setScale(2, BigDecimal.ROUND_HALF_DOWN);
                } else {
                    nVlrTotal = nVlrParcela;
                }
                // APLICA O DESCONTO
                nVlrTotal = nVlrTotal.subtract(nVlrDesconto);
                
                // CALCULA VALOR DOS IMPOSTOS
                if (nVlrTotal.intValue() > selectContaPagarParcela.getVlrParcela().intValue()) {
                    nVlrImposto = nVlrTotal.subtract(selectContaPagarParcela.getVlrParcela());
                } else {
                    nVlrImposto = selectContaPagarParcela.getVlrParcela().subtract(nVlrTotal);
                }

                selectContaPagarParcela.setVlrMultaParcela(nVlrMulta);
                selectContaPagarParcela.setVlrJuros(nVlrJuros);
                selectContaPagarParcela.setVlrPago(nVlrTotal);
                selectContaPagarParcela.setTipStatus("P");
                selectContaPagarParcela.setVlrImposto(nVlrImposto);

                this.selectedContaPagar.getContaPagarParcelaList().set(this.rowid, selectContaPagarParcela);

                this.alterarPagar(event);

                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Baixa efetuada com sucesso!", selectedContaPagar.getDscPagar()));
            }
        } catch (Exception ex) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Erro de Processamento ...", selectedContaPagar.getDscPagar()));
        }
    }

    public void baixarManualParcela(ActionEvent event) {
        BigDecimal nVlrJuros = selectContaPagarParcela.getVlrJuros();
        BigDecimal nVlrMulta = selectContaPagarParcela.getVlrMultaParcela();

        BigDecimal nVlrParcela = selectContaPagarParcela.getVlrParcela();
        BigDecimal nVlrDesconto = selectContaPagarParcela.getVlrDescontoParcela();
        BigDecimal nVlrTotal = selectContaPagarParcela.getVlrPago();
        BigDecimal nVlrImposto = new BigDecimal(0);

        try {
            if (selectContaPagarParcela.getDatVcto() == null) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Data Vencimento Inválida!", selectedContaPagar.getDscPagar()));
            } else if (selectContaPagarParcela.getDatPagto() == null) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Data Pagamento Inválida!", selectedContaPagar.getDscPagar()));
            } else if (nVlrParcela.compareTo(BigDecimal.ZERO) == 0) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Valor da Parcela Obrigatório!", selectedContaPagar.getDscPagar()));
            } else if (selectContaPagarParcela.getIdBaixa() == null) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Obrigatório selecionar Tipo de Baixa!", selectedContaPagar.getDscPagar()));
            } else if (selectContaPagarParcela.getIdPagamento() == null) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Obrigatório selecionar Tipo de Pagamento!", selectedContaPagar.getDscPagar()));
            } else {
                nVlrTotal = nVlrParcela.subtract(nVlrDesconto).add(nVlrMulta).add(nVlrJuros);
                // CALCULA VALOR DOS IMPOSTOS
                if (nVlrTotal.intValue() > selectContaPagarParcela.getVlrParcela().intValue()) {
                    nVlrImposto = nVlrTotal.subtract(selectContaPagarParcela.getVlrParcela());
                } else {
                    nVlrImposto = selectContaPagarParcela.getVlrParcela().subtract(nVlrTotal);
                }
                selectContaPagarParcela.setVlrMultaParcela(nVlrMulta);
                selectContaPagarParcela.setVlrJuros(nVlrJuros);
                selectContaPagarParcela.setVlrPago(nVlrTotal);
                selectContaPagarParcela.setTipStatus("P");
                selectContaPagarParcela.setVlrImposto(nVlrImposto);

                this.selectedContaPagar.getContaPagarParcelaList().set(this.rowid, selectContaPagarParcela);

                this.alterarPagar(event);

                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Baixa efetuada com sucesso!", selectedContaPagar.getDscPagar()));
            }
        } catch (Exception ex) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Erro de Procesamento ...", selectedContaPagar.getDscPagar()));
        }
    }

    public void gravarParcela(ActionEvent event) {
        try {
            if (selectContaPagarParcela.getDatPagto() != null) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Data Pagamento preenchida - Utilize Baixa", selectedContaPagar.getDscPagar()));
            } else if (selectContaPagarParcela.getVlrPago().compareTo(BigDecimal.ZERO) > 0) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Valor Recebido preenchido - Utilize Baixa", selectedContaPagar.getDscPagar()));
            } else {
                this.selectedContaPagar.getContaPagarParcelaList().set(this.rowid, selectContaPagarParcela);

                this.alterarPagar(event);
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Gravação efetuada com sucesso!", selectedContaPagar.getDscPagar()));
            }
        } catch (Exception ex) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Erro de Procesamento ...", selectedContaPagar.getDscPagar()));
        }
    }

    public boolean isSalvar() {
        return salvar;
    }

    public void setSalvar(boolean salvar) {
        this.salvar = salvar;
    }

    public boolean ValidaPagar() {
        boolean lReturn = true;

        if (this.selectedContaPagar.getDscPagar().isEmpty()) {
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERRO - Descrição em Branco!", "");
            lReturn = false;
        } else if (this.selectedContaPagar.getIdFornecedor() == null) {
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERRO - Obrigatório Definir o Fornecedor!", "");
            lReturn = false;
        } else if (this.selectedContaPagar.getIdCusto() == null) {
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERRO - Obrigatório Definir o Centro de Custo!", "");
            lReturn = false;
        } else if (this.selectedContaPagar.getVlrPagar().floatValue() <= 0) {
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERRO - Valor a Pagar não Definido!", "");
            lReturn = false;
        } else if (this.selectedContaPagar.getContaPagarParcelaList().isEmpty()) {
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERRO - Obrigatório Definir a Parcela!", "");
            lReturn = false;
        }
        return lReturn;
    }

    public void eliminaParcelas() {
        String cSql = "delete from conta_pagar_parcela "
                + "where id_parcela not in (select id_parcela from conta_pagar_conta_pagar_parcela)";
        try {
            ContaPagarJpa.getNativeFiltro(cSql);
        } catch (Exception ex) {
            Logger.getLogger(ContaPagarBean.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public int getRowid() {
        return rowid;
    }

    public void setRowid(int rowid) {
        this.rowid = rowid;
    }

}
